import { useEffect, useMemo, useState } from 'react'
import dayjs from 'dayjs'
import { DatePicker, Input, message, Select, SelectProps, Typography } from 'antd'
import Icon from '@ant-design/icons'

import { apiGetAddressList, apiGetFirstLegInformation, apiSetFirstLegInformation } from '../../apis'
import { IAddressListReq, IFirstLegInformationRes, ISetFirstLegInformationReq } from '../../interface'
import { getFirstLineName, getTransportationTypeName, useUrlParams } from '../../utils'
import { CardHeaderEdit } from '../CardHeaderEdit'
import EditableForm from '../EditableForm'
import { FormSchemaItem } from '../EditableForm/interface'
import { TwoInputFields } from './TwoInputFields'
import styles from './styles.module.less'

const formSchemaConfig = ({ addressOptions }: { addressOptions: SelectProps['options'] }): FormSchemaItem[] => [
  {
    name: 'icon',
    editable: false,
    dependencies: ['transportType'],
    span: ({ record }) => (record?.transportType ? 2 : 0),
    hidden: ({ record }) => !record?.transportType,
    renderView: ({ record }) => {
      const type = record?.transportType as 1 | 2 | 3 | 4 | null | undefined
      const TransportIcon = type ? getTransportationTypeName.iconMap[type] : undefined
      return TransportIcon ? <Icon component={TransportIcon} className={styles.icon} /> : null
    },
  },
  {
    label: '运输方式',
    span: ({ record }) => (record?.transportType ? 10 : 12),
    name: 'transportType',
    component: Select,
    componentProps: {
      allowClear: true,
      options: getFirstLineName.valueList.map(value => ({
        label: getFirstLineName(value),
        value,
      })),
    },
    renderView: ({ record, name }) => getFirstLineName(record[name] || ''),
  },
  {
    label: '承运商',
    name: 'carrier',
    component: Input,
  },
  {
    label: '船名航次',
    name: 'voyage',
    component: TwoInputFields,
    componentProps: {
      keys: ['vesselName', 'voyageNumber'],
    },
    dependencies: ['transportType'],
    renderView: ({ record, name }) => `${record[name]?.vesselName || ''} ${record[name]?.voyageNumber || ''}`,
    hidden: ({ record }) => getFirstLineName(record?.transportType || '') !== 'OCEAN',
  },
  {
    label: '柜号',
    name: 'containerNumber',
    component: Input,
    dependencies: ['transportType'],
    hidden: ({ record }) => getFirstLineName(record?.transportType || '') !== 'OCEAN',
    renderView: ({ record, name }) => (
      <Typography.Text className={styles.ellipsis} ellipsis={{ tooltip: record[name] }}>
        {record[name]}
      </Typography.Text>
    ),
  },
  {
    label: '航班号',
    name: 'flightNumber',
    component: Input,
    dependencies: ['transportType'],
    hidden: ({ record }) => getFirstLineName(record?.transportType || '') !== 'AIR',
  },
  {
    label: '车次',
    name: 'trainTruckNumber',
    component: Input,
    dependencies: ['transportType'],
    hidden: ({ record }) =>
      !['GROUND_TRUCK', 'GROUND_TRAIN'].includes(getFirstLineName(record?.transportType || '') || ''),
  },
  {
    label: ({ record }) => (getFirstLineName(record?.transportType) === 'AIR' ? '起飞机场' : '起运港'),
    name: 'departureLocationId',
    component: Select,
    dependencies: ['transportType'],
    componentProps: {
      options: addressOptions,
    },
    renderView: ({ record }) => {
      return record['departureLocationName'] || '-'
    },
  },
  {
    name: 'departureLocationName',
    hidden: true,
    editable: false,
  },
  {
    label: ({ record }) => (getFirstLineName(record?.transportType) === 'AIR' ? '落地机场' : '目的港'),
    name: 'destinationLocationId',
    component: Select,
    dependencies: ['transportType'],
    componentProps: {
      options: addressOptions,
    },
    renderView: ({ record }) => record['destinationLocationName'] || '-',
  },
  {
    name: 'destinationLocationName',
    hidden: true,
    editable: false,
  },
  {
    label: 'ETD',
    name: 'etd',
    component: DatePicker,
    renderView: ({ record, name }) => (record[name] ? dayjs(record[name]).format($F_YMD) : '-'),
  },
  {
    label: 'ETA',
    name: 'eta',
    component: DatePicker,
    renderView: ({ record, name }) => (record[name] ? dayjs(record[name]).format($F_YMD) : '-'),
  },
]

export const FirstInfo = () => {
  const [form] = EditableForm.useForm()
  const [edit, setEdit] = useState(false)
  const { waybillNo } = useUrlParams()
  const [firstLegInformation, setFirstLegInformation] = useState<IFirstLegInformationRes>()
  const [addressOptions, setAddressOptions] = useState<SelectProps['options']>()

  const initForm = (info: IFirstLegInformationRes) => {
    form.setFieldsValue({
      transportType: info?.transportType,
      carrier: info?.carrier,
      vesselName: info?.vesselName,
      voyage: {
        vesselName: info?.vesselName,
        voyageNumber: info?.voyageNumber,
      },
      containerNumber: info?.containerNumber,
      trainTruckNumber: info?.trainTruckNumber,
      departureLocationId: info?.departureLocationId,
      departureLocationName: info?.departureLocationName,
      destinationLocationId: info?.destinationLocationId,
      destinationLocationName: info?.destinationLocationName,
      etd: info?.etd ? dayjs(info?.etd) : null,
      eta: info?.eta ? dayjs(info?.eta) : null,
    })
  }

  const cancel = () => {
    setEdit(false)
    if (firstLegInformation) {
      initForm(firstLegInformation)
    }
  }

  const getAddressList = async (addressType: IAddressListReq['addressType']) => {
    const res = await apiGetAddressList({ addressType: addressType === 4 ? 1 : addressType })
    if (res) {
      setAddressOptions(
        res.map(item => ({
          label: item.chineseName,
          value: item.addressId,
        })),
      )
    }
  }

  const getFirstLegInformationInfo = async () => {
    const res = await apiGetFirstLegInformation({ waybillNo: waybillNo })
    if (res) {
      setFirstLegInformation(res)
      if (res?.transportType) getAddressList(res?.transportType)
      initForm(res)
    }
  }

  const formSchema = useMemo(() => {
    return formSchemaConfig({ addressOptions })
  }, [addressOptions])

  const onValuesChange = (values: ISetFirstLegInformationReq) => {
    if (values.transportType) {
      getAddressList(values.transportType)
      form.resetFields(['departureLocationId', 'destinationLocationId'])
    }
    if (values.departureLocationId) {
      form.setFieldValue(
        'departureLocationName',
        addressOptions?.find(item => item.value === values.departureLocationId)?.label,
      )
    }
    if (values.destinationLocationId) {
      form.setFieldValue(
        'destinationLocationName',
        addressOptions?.find(item => item.value === values.destinationLocationId)?.label,
      )
    }
  }

  const save = async () => {
    const { transportType, voyage, etd, eta, ...rest } = await form.getFieldsValue()
    if (!transportType || !rest.carrier || !rest.departureLocationId || !rest.destinationLocationId) {
      return message.error('请检查填写内容')
    }
    if (transportType === 1 && (!voyage?.vesselName || !voyage?.voyageNumber)) {
      return message.error('请检查填写内容')
    }
    if (transportType === 2 && !rest.flightNumber) {
      return message.error('请检查填写内容')
    }
    if ([3, 4].includes(transportType) && !rest.trainTruckNumber) {
      return message.error('请检查填写内容')
    }
    apiSetFirstLegInformation({
      waybillNo: waybillNo,
      transportType,
      vesselName: voyage?.vesselName,
      voyageNumber: voyage?.voyageNumber,
      etd: etd ? etd?.format($F_YMD) : null,
      eta: eta ? eta?.format($F_YMD) : null,
      ...rest,
    })
      .then(() => {
        message.success('保存成功')
        getFirstLegInformationInfo()
      })
      .finally(() => {
        setEdit(false)
      })
  }

  useEffect(() => {
    getFirstLegInformationInfo()
  }, [])

  return (
    <>
      <CardHeaderEdit title="头程信息" edit={edit} save={save} cancel={cancel} openEdit={() => setEdit(true)} />
      <EditableForm
        form={form}
        editable={edit}
        formSchema={formSchema}
        formProps={{ layout: 'vertical', onValuesChange }}
      />
    </>
  )
}
